package vip.xiaonuo.smzq.core.utils;

import org.geotools.data.FeatureSource;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.geojson.feature.FeatureJSON;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.referencing.CRS;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import org.opengis.feature.GeometryAttribute;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.type.GeometryType;
import org.opengis.feature.type.Name;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * @program:
 * @description: shp文件操作工具类
 * @author: 高天乐
 * @create: 2023-08-17 10:49
 **/
public class ShpUtil {

    /**
     * 获取shp文件路径
     *
     * @param filePath        存放shp的文件夹路径
     * @param shpFilePathList 存储shp文件路径集合
     */
    public static void getShpFilePath(String filePath, Map<String, String> shpFilePathList) {
        //打开shp文件夹
        File fileFolder = new File(filePath);
        //获取文件夹中的文件
        File[] files = fileFolder.listFiles();
        for (File file : files) {
            if (file.isDirectory()) {
                getShpFilePath(file.getPath(), shpFilePathList);
                continue;
            }
            String name = file.getName();
            if (name.substring(name.length() - 3).equalsIgnoreCase("shp")) {
                shpFilePathList.put(name, file.getPath());
            }
        }
    }

    /**
     * 解析prj文件，获取坐标系
     *
     * @param shpFilePath prj文件路径
     * @return 坐标系的code ，例如3857,4326等等
     */
    public static Integer getSrid(String shpFilePath) {
        ShapefileDataStore dataStore = buildDataStore(shpFilePath);
        Integer code = null;
        try {
            String wkt = dataStore.getSchema().getCoordinateReferenceSystem().toWKT();
            CoordinateReferenceSystem crsTarget = CRS.parseWKT(wkt);
            code = CRS.lookupEpsgCode(crsTarget, true);
        } catch (UnsupportedOperationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (FactoryException e) {
            e.printStackTrace();
        } finally {
            dataStore.dispose();
        }
        return code;
    }

    /**
     * 构建ShapeDataStore对象。
     *
     * @param shpFilePath shape文件路径。
     * @return
     */
    public static ShapefileDataStore buildDataStore(String shpFilePath) {
        ShapefileDataStoreFactory factory = new ShapefileDataStoreFactory();
        ShapefileDataStore dataStore = null;
        try {
            dataStore = (ShapefileDataStore) factory
                    .createDataStore(new File(shpFilePath).toURI().toURL());
            if (dataStore != null) {
                dataStore.setCharset(StandardCharsets.UTF_8);
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return dataStore;
    }

    /**
     * 读取shp文件转为geojson
     *
     * @param path shp路径地址 例：E:/shp文件夹/三调/sandiao.shp
     * @return
     */
    public static String readShpTransitionGeoJson(String path) throws IOException {
        ShapefileDataStore dataStore = new ShapefileDataStore(new File(path).toURI().toURL());
        // 处理中文乱码
        dataStore.setCharset(StandardCharsets.UTF_8);
        //获取数据资源
        FeatureSource featureSource = dataStore.getFeatureSource();
        FeatureJSON featureJSON = new FeatureJSON();
        String result = null;
        try (StringWriter writer = new StringWriter()) {
            featureJSON.writeFeatureCollection(featureSource.getFeatures(), writer);
            result = writer.toString();
        }
        return result;
    }

    /**
     * 解析shp文件 示例
     *
     * @param shpPath shp文件地址
     * @throws IOException
     */
    public void readShpContent(String shpPath) throws IOException, FactoryException {
        //"D:/kczyjg/upload/2023/08/10/shp1_20230810173842A002/shp1/坐标shp.shp"
        File file = new File(shpPath);
        //打开shp文件资源管理器
        ShapefileDataStore shape = new ShapefileDataStore(file.toURL());
        //设置编码
        shape.setCharset(Charset.forName("GBK"));
//        //打开文件资源管理器
//        FileDataStore store = FileDataStoreFinder.getDataStore(file);
        //获取feature资源
        SimpleFeatureSource featureSource = shape.getFeatureSource();
        //获取一个shp中的feature集合
        SimpleFeatureCollection features = featureSource.getFeatures();
        //遍历集合
        SimpleFeatureIterator iterator = features.features();
        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
        while (iterator.hasNext()) {
            //获取一个单独的feature
            SimpleFeature feature = iterator.next();
            // 要素geometry的类型和坐标，如点，线，面及其组成的坐标
            Geometry geometry = TransFormUtil.coordinateTransform(feature, 4490);
            //计算中心点坐标
            Coordinate coordinate = geometry.getCentroid().getCoordinate();
            Point centerPoint = geometryFactory.createPoint(coordinate);
            // geometry属性
            GeometryAttribute geometryAttribute = feature.getDefaultGeometryProperty();
            //获取字段值 xkzh、name...
            // 获取字段值
//            Object xkzh = feature.getAttribute("xkzh");
//            Object wtlx = feature.getAttribute("name");
            // geometry类型
            GeometryType geometryType = geometryAttribute.getType();
            // geometry类型名称
            Name name = geometryType.getName();
            // 获取坐标参考系信息
            CoordinateReferenceSystem coordinateReferenceSystem = geometryAttribute.getDescriptor().getCoordinateReferenceSystem();
            String code = "";
            if (coordinateReferenceSystem != null) {
                code = coordinateReferenceSystem.getCoordinateSystem().getName().getCode();
            }
        }
        iterator.close();
    }
}
